package com.mew.auc.service;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.mew.auc.data.LoginData;
import com.mew.auc.util.SnowflakeUtil;
import com.mew.common.config.RedisConstantValue;
import com.mew.common.dc.mapper.*;
import com.mew.common.enm.GoldProcessType;
import com.mew.common.enm.MailAccessoryType;
import com.mew.common.enm.PropType;
import com.mew.common.enm.UserType;
import com.mew.common.entity.events.Events;
import com.mew.common.entity.mail.Accessory;
import com.mew.common.entity.mail.Mail;
import com.mew.common.entity.prop.Prop;
import com.mew.common.entity.user.GameId;
import com.mew.common.entity.user.User;
import com.mew.common.exception.MewException;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.Date;

/**
 * @author yanglin
 */
@Service
@Slf4j
@Transactional
public class WebLoginService {

    @Autowired
    UserMapper userMapper;

    @Autowired
    GameIdMapper gameIdMapper;

    @Autowired
    ThirdUserMapper thirdUserMapper;
    @Autowired
    EventsMapper eventsMapper;
    @Autowired
    SnowflakeUtil snowflakeUtil;

    @Autowired
    MailUtilService mailUtilService;

    @Autowired
    WhiteListService whiteListService;
    @Autowired
    private PropMapper propMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;


    public LoginData guestLogin(String mac, String gid, String ip){

        LoginData loginData = null;

        User user = userMapper.getGuest(mac, gid);
        if(user != null){
            loginData = buildLoginData(user,  false);
            updateLoginInfo(user, loginData);
        }
        return loginData;
    }

    public LoginData guestLoginByMac(String mac, String ip){

        LoginData loginData = null;

        User user = userMapper.getUserByMac(mac);
        boolean isFirst = false;
        if(user == null){
            user = createGuest(mac, ip);
            isFirst = true;
        }

        if(user != null)
        {
            loginData = buildLoginData(user,  isFirst);
            updateLoginInfo(user, loginData);
        }
        return loginData;
    }



    public LoginData accountLogin(String account, String password, String ip, String mac){
        LoginData loginData = null;

        User user = userMapper.getUserByAccount(account, password);
        if(user != null){

            String firstMac = user.getFirstMac();
            if(firstMac == null || firstMac.equals("")){
                LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(User::getId, user.getId()).set(User::getFirstMac, mac).set(User::getAddIp, ip);
                userMapper.update(null, updateWrapper);
            }


            loginData = buildLoginData(user, false);
            updateLoginInfo(user, loginData);
        }
        return loginData;
    }

    private LoginData buildLoginData(User user,   boolean isFirst){

        LoginData loginData = new LoginData();

        boolean inWhiteList = whiteListService.isInWhiteList(user.getId());
        user.setWhiteList(inWhiteList ? 1 : 0);

        loginData.setId(user.getId());
        loginData.setState(user.getState());

        loginData.setGid(user.getGid());
        loginData.setTelNumber(user.getTelNumber());
        loginData.setNickname(user.getNickname());
        loginData.setHeadPath(user.getHeadPath());

        loginData.setGuideType(user.getGuideType());
        if(user.getAccountType() == null) {
            loginData.setUserType(0);
        }
        else{
            loginData.setUserType(user.getAccountType());
        }
        loginData.setFirst(isFirst);
        loginData.setInWhiteList(inWhiteList);

        return loginData;
    }

    private void updateLoginInfo(User user, LoginData loginData){

        if(loginData.isFirst() && user.getUserType() != 0)
        {
            long gold = 5000;
            Mail mail=Mail.builder()
                    .type(GoldProcessType.ThirdRegister.code())
                    .title("รางวัลการล็อกอิน")
                    .content("ยินดีด้วย คุณได้รับรางวัล "+gold+"เหรียญทองสำหรับการเข้าสู่ระบบครั้งแรก")
                    .sendTime(new Date())
                    .receiveUser(user.getId())
                    .status(0)
                    .build();
            Accessory accessory=Accessory.builder()
                    .type(MailAccessoryType.Gold.code())
                    .quantity(gold)
                    .build();
            mailUtilService.insertMail(mail,accessory);
        }
        redisTemplate.opsForHash().put(RedisConstantValue.USER_INFO, user.getId(), user);
    }

    //TODO:Performance


    private User createGuest(String mac, String ip){
        try {
            User user = new User();
            user.setAddMac(mac);
            user.setFirstMac(mac);
            user.setAddIp(ip);

            user.setState(1);
            user.setHeadPath(0);
            user.setSex(0);
            user.setGuideType(0);
            user.setAddTime(new Date());
            user.setUserType(UserType.Common.code());
            user.setAccountType(0);

            userMapper.insert(user);

            GameId gameId = gameIdMapper.selectById(user.getId());
            if(gameId == null || gameId.getGid() == null){
                throw new MewException("获取gameId失败，请检查u_game_id表是否耗尽");
            }

            user.setGid(gameId.getGid());
            user.setNickname("Player-" + gameId.getGid());

            updateNickname(user.getId(), user.getNickname(), user.getGid());

            Events events = new Events();
            events.setUserId(user.getId());
            eventsMapper.insert(events);

            createEditNameCard(user);

            return user;
        }
        catch (Exception e)
        {
            TransactionAspectSupport.currentTransactionStatus()
                    .setRollbackOnly();
            log.error("createGuest:", e);
            return null;
        }
    }

    private void updateNickname(long id, String nickname, String gid){

        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId, id).set(User::getNickname, nickname).set(User::getGid, gid);
        userMapper.update(null, updateWrapper);
    }

    /**
     * 建立账号送一张改名卡
     * @param user
     */
    public void createEditNameCard(User user){
        propMapper.insert(Prop.builder()
                .propTypeId(PropType.EditNameCard.code())
                .userId(user.getId())
                .number(1L)
                .status(0)
                .build());
    }
}
